/**

  Canvas Measurement Algorithm adopted from Font.js v2012.01.25
  Adjusted Quad Size for accurate results cross broswers.
  Added accurate layout for baseline, ascent and descent.

**/

  if(!document.createElement("canvas").getContext) {
    throw("vTex requires <canvas> and the Canvas2D API. Please update your browswer or Download modern WebBrowers like Safari/Google Chrome/Firefox");
  }
  
    
  var quad=0;
  
  var Font={};

  var metrics = {
  	ascent:0,
  	descent:0,
  	width:0,
  	height:0,
    maxx:0,
    maxy:0,
    minx:0,
    miny:0
  };
  
  
  function error (err) { alert(err); };
  
  Font.canvas = null;
  Font.context = null;


  function prepareCanvas () {

      var canvas = document.createElement("canvas");
      
//      document.body.appendChild(canvas);
      
      canvas.width = quad;
      canvas.height = quad;
      Font.canvas = canvas;
      
      var context = canvas.getContext("2d");
      Font.context = context;
      
      Font.context.font = Font.size + "px '"+Font.fontFamily+"'";
    
	  measureSegment(Font.text, Font.size);
    
  };


  function measureSegment (textSegment, fontSize) {

    var canvas = Font.canvas,
     ctx = Font.context,
     w = quad,
     h = quad,
     baseline = quad / 2,
     padding = 0, 
     xpos = (quad - Font.size*2) / 2;

    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, w , h );
 
    ctx.fillStyle = "black";
    ctx.fillText(textSegment, xpos, baseline);
    ctx.textBaseline="alphabetic";
    
    metrics.width=ctx.measureText(textSegment).width;
   

	var scanwidth = Font.size*2,
        scanheight = 2 * fontSize,
        x_offset = xpos,
        y_offset = baseline-scanheight / 2;
        
    var pixelData = ctx.getImageData(x_offset, y_offset, scanwidth, scanheight).data;
        
		
    var i = 0,
        j = 0,
        w4 = scanwidth * 4,
        len = pixelData.length,
        mid = scanheight / 2;
        
    // Scan 1: find the ascent using a normal, forward scan
    while (++i < len && pixelData[i] >= 200) {}
    var ascent = ((i / w4))|0;

    // Scan 2: find the descent using a reverse scan
    i = len - 1;
    while (--i > 0 && pixelData[i] >= 200) {}
    var descent = ((i / w4))|0 ;

    // Scan 3: find the min-x value, using a forward column scan
//    for (i = 0, j = 0; j < scanwidth && pixelData[i] >=200;) {
//      i += w4;
//      if (i >= len) { j++; i = (i - len) + 4; }}
//    var minx = j;

    // Scan 3: find the max-x value, using a reverse column scan
//    j=0;
//    var step = 1;
//    for (i = len-3, j = 0; j<scanwidth && pixelData[i] >=200; ) {
//      i -= w4;
//      if (i < 0) { j++; i = (len - 3) - (step++) * 4; }
//      }
      
//    var maxx = scanwidth - j;

   
    metrics.ascent  = (mid - ascent);
    metrics.descent = (descent - mid);
    metrics.height = (descent - ascent);
    metrics.miny=-metrics.descent;
    metrics.maxy=metrics.ascent;
    
//    ctx.beginPath();
//    ctx.rect(minx+xpos,ascent+y_offset,metrics.width,metrics.height);
//    ctx.lineWidth=0;
//    ctx.strokeStyle="grey";
//    ctx.stroke();
    
//    ctx.beginPath();
//    ctx.moveTo(minx+xpos-5,baseline);
//    ctx.lineTo(metrics.width+minx+xpos+5,baseline);
//	ctx.lineWidth=1.2;
//    ctx.strokeStyle="blue";
//    ctx.stroke();
    
//    ctx.beginPath();
//    ctx.moveTo(minx+xpos-5,ascent+y_offset);
//    ctx.lineTo(metrics.width+minx+xpos+5,ascent+y_offset);
//	ctx.lineWidth=1.2;
//    ctx.strokeStyle="green";
//    ctx.stroke();
    
//    ctx.beginPath();
//    ctx.moveTo(minx+xpos-5,descent+y_offset);
//    ctx.lineTo(metrics.width+minx+xpos+5,descent+y_offset);
//	ctx.lineWidth=1.2;
//    ctx.strokeStyle="red";
//    ctx.stroke();

	Font.canvas=null;
    

  };

  function textMetrics(textFont,text,size) {
	
	var result=null;
	
 	Font.fontFamily=textFont;
 	Font.text=text;
 	Font.size=size;
 	quad=size*3;
 	
 	
 	prepareCanvas();
 
 	return metrics;
 
}
	
